package com.lenovo.lcdm.type.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lenovo.lcdm.common.enums.CommonMsgEnum;
import com.lenovo.lcdm.common.enums.DeleteFlagEnum;
import com.lenovo.lcdm.common.enums.ResponseMsgEnum;
import com.lenovo.lcdm.common.exception.BusinessException;
import com.lenovo.lcdm.common.exception.ServiceException;
import com.lenovo.lcdm.type.util.ContextUtil;
import com.lenovo.lcdm.type.dto.AttributeFolderDTO;
import com.lenovo.lcdm.type.dto.GlobalAttributeDTO;
import com.lenovo.lcdm.type.entity.TypeAttributeFolder;
import com.lenovo.lcdm.type.entity.TypeDataType;
import com.lenovo.lcdm.type.entity.TypeGlobalAttribute;
import com.lenovo.lcdm.type.mapper.TypeAttributeFolderMapper;
import com.lenovo.lcdm.type.service.TypeAttributeFolderService;
import com.lenovo.lcdm.type.service.TypeDataTypeService;
import com.lenovo.lcdm.type.service.TypeGlobalAttributeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author xujing30
* @description 针对表【type_attribute_folder】的数据库操作Service实现
* @createDate 2024-01-03 16:30:51
*/
@Service
public class TypeAttributeFolderServiceImpl extends ServiceImpl<TypeAttributeFolderMapper, TypeAttributeFolder>
    implements TypeAttributeFolderService{

    /** Root属性ID */
    private static final Long ROOT_ID = 0L;

    /** Root属性名称 */
    private static final String ROOT_NAME = "Root";

    @Autowired
    private TypeGlobalAttributeService globalAttributeService;

    @Autowired
    private TypeDataTypeService dataTypeService;

    @Override
    public AttributeFolderDTO queryRootFolder() {
        // 构建Root属性信息
        AttributeFolderDTO rootAttributeFolderDto = new AttributeFolderDTO();
        rootAttributeFolderDto.setId(ROOT_ID);
        rootAttributeFolderDto.setName(ROOT_NAME);

        List<AttributeFolderDTO> childAttributeFolds = new ArrayList<>();
        List<TypeAttributeFolder> attributeFolderList = this.queryRootChild();
        // 构建Root子节点信息
        AttributeFolderDTO attributeFolderDto = null;
        for (TypeAttributeFolder attributeFolder : attributeFolderList) {
            attributeFolderDto = new AttributeFolderDTO();
            attributeFolderDto.setId(attributeFolder.getId());
            attributeFolderDto.setName(attributeFolder.getName());
            attributeFolderDto.setParentId(attributeFolder.getParentId());
            childAttributeFolds.add(attributeFolderDto);
        }
        rootAttributeFolderDto.setChildAttributeFolders(childAttributeFolds);
        return rootAttributeFolderDto;
    }

    @Override
    public List<TypeAttributeFolder> queryRootChild() {
        LambdaQueryWrapper<TypeAttributeFolder> qw = new LambdaQueryWrapper();
        qw.eq(TypeAttributeFolder::getParentId, ROOT_ID);
        return list(qw);
    }

    @Override
    public AttributeFolderDTO queryFolderAttribute() {
        // 构建Root属性信息
        AttributeFolderDTO rootAttributeFolderDto = new AttributeFolderDTO();
        rootAttributeFolderDto.setId(ROOT_ID);
        rootAttributeFolderDto.setName(ROOT_NAME);

        List<AttributeFolderDTO> childAttributeFolds = new ArrayList<>();
        List<TypeAttributeFolder> attributeFolderList = queryRootChild();

        List<TypeDataType> TypeDataTypeList = dataTypeService.findAll();
        // 将所有数据类型放入Map
        Map<Long, TypeDataType> dataTypeMap = new HashMap<>();
        for (TypeDataType dataType : TypeDataTypeList) {
            dataTypeMap.put(dataType.getId(), dataType);
        }
        
        // 一次取出全局属性,构建Map集合
        Map<Long, List<TypeGlobalAttribute>> globalAttributeMap = new HashMap<>();
        List<TypeGlobalAttribute> TypeGlobalAttributeList = globalAttributeService.findAll();
        for (TypeGlobalAttribute globalAttribute : TypeGlobalAttributeList) {
            if (globalAttributeMap.containsKey(globalAttribute.getAttributeFolderId())) {
                globalAttributeMap.get(globalAttribute.getAttributeFolderId()).add(globalAttribute);
            } else {
                List<TypeGlobalAttribute> globalAttributeList = new ArrayList<>();
                globalAttributeList.add(globalAttribute);
                globalAttributeMap.put(globalAttribute.getAttributeFolderId(), globalAttributeList);
            }
        }

        // 构建Root子节点信息
        AttributeFolderDTO attributeFolderDto = null;
        for (TypeAttributeFolder attributeFolder : attributeFolderList) {
            attributeFolderDto = new AttributeFolderDTO();
            attributeFolderDto.setId(attributeFolder.getId());
            attributeFolderDto.setName(attributeFolder.getName());
            attributeFolderDto.setParentId(attributeFolder.getParentId());
            TypeGlobalAttributeList = null;
            if (globalAttributeMap.containsKey(attributeFolder.getId())) {
                TypeGlobalAttributeList = globalAttributeMap.get(attributeFolder.getId());
            }
            if (!CollectionUtils.isEmpty(TypeGlobalAttributeList)) {
                List<GlobalAttributeDTO> attributeDtoList = new ArrayList<>();
                GlobalAttributeDTO globalAttributeDto = null;
                for (TypeGlobalAttribute TypeGlobalAttribute : TypeGlobalAttributeList) {
                    globalAttributeDto = new GlobalAttributeDTO();

                    BeanUtils.copyProperties(TypeGlobalAttribute, globalAttributeDto);

                    TypeDataType dataType = dataTypeMap.get(TypeGlobalAttribute.getDataTypeId());
                    if (!ObjectUtils.isEmpty(dataType)) {
                        globalAttributeDto.setDataTypeName(dataType.getName());
                    }
                    attributeDtoList.add(globalAttributeDto);
                }

                attributeFolderDto.setGlobalAttributes(attributeDtoList);
            }
            childAttributeFolds.add(attributeFolderDto);

        }
        rootAttributeFolderDto.setChildAttributeFolders(childAttributeFolds);
        return rootAttributeFolderDto;
    }

    private String checkFolder(String name, Long parentId){
        StringBuilder builder = new StringBuilder();
        if (StringUtils.isBlank(name)) {
            builder.append("name not null");
        }

        if (ObjectUtils.isEmpty(parentId)) {
            builder.append("parentId not null");
        }

        String errorMessage = validateFolderName(name, null, true);
        if (StringUtils.isNotEmpty(errorMessage)) {
            builder.append(errorMessage);
        }
        return builder.toString();
    }

    /**
     * 属性文件夹名称是否存在
     *
     * @param folderName 属性文件夹名称
     * @param id         属性文件夹Id
     * @param isCreate   是否新增操作
     * @return
     */
    private String validateFolderName(String folderName, Long id, boolean isCreate) {
        StringBuffer buffer = new StringBuffer();

        if (isCreate) {
            List<TypeAttributeFolder> attributeFolderList = queryByFolderName(folderName);

            if (!CollectionUtils.isEmpty(attributeFolderList)) {
                buffer.append("the AttributeFolder name is used");
            }
        } else {
            List<TypeAttributeFolder> attributeFolderList = queryByFolderName(folderName);
            // 如果找到同名的对象，并且不是本身
            if (!CollectionUtils.isEmpty(attributeFolderList)) {
                TypeAttributeFolder attributeFolder = attributeFolderList.get(0);
                if (!attributeFolder.getId().equals(id)) {
                    buffer.append("the AttributeFolder name is used");
                }
            }
        }
        return buffer.toString();
    }

    @Override
    public List<TypeAttributeFolder> queryByFolderName(String name) {
        LambdaQueryWrapper<TypeAttributeFolder> qw = new LambdaQueryWrapper<>();
        qw.eq(TypeAttributeFolder::getName, name).eq(TypeAttributeFolder::getDeleted, DeleteFlagEnum.NO.getValue());
        return list(qw);
    }

    @Override
    public AttributeFolderDTO saveFolder(String name, Long parentId) {
        // 参数不能为空
        String errorMsg = checkFolder(name, parentId);
        if(StringUtils.isNotEmpty(errorMsg)){
            throw new BusinessException(errorMsg, CommonMsgEnum.FAIL.getCode());
        }

        AttributeFolderDTO attributeFolderDto = new AttributeFolderDTO();

        TypeAttributeFolder attributeFolder = new TypeAttributeFolder();
        attributeFolder.setParentId(parentId);
        attributeFolder.setName(name);
        attributeFolder.setCreateTime(LocalDateTime.now());
        attributeFolder.setCreator(ContextUtil.getCurrentUser());
        attributeFolder.setModifyTime(LocalDateTime.now());
        attributeFolder.setModifier(ContextUtil.getCurrentUser());
        attributeFolder.setObjectClass(attributeFolder.getClass().getName());
        saveOrUpdate(attributeFolder);
        attributeFolderDto.setName(name);
        attributeFolderDto.setId(attributeFolder.getId());
        attributeFolderDto.setParentId(parentId);
        return attributeFolderDto;
    }

    @Override
    public void updateFolder(String name, Long id){
        String errorMessage = validateFolderName(name, id, false);
        if (StringUtils.isNotEmpty(errorMessage)) {
            throw new BusinessException(errorMessage, ResponseMsgEnum.FAIL.getCode());
        } else {
            TypeAttributeFolder attributeFolder = getById(id);
            if (null != attributeFolder) {
                attributeFolder.setName(name);
                attributeFolder.setModifyTime(LocalDateTime.now());
                attributeFolder.setModifier(ContextUtil.getCurrentUser());
                saveOrUpdate(attributeFolder);
            } else {
                throw new ServiceException("Cannot find attribute folder in system" ,CommonMsgEnum.FAIL.getCode());
            }
        }
    }

    @Override
    public void deleteFolder(Long id) {
        TypeAttributeFolder attributeFolder = getById(id);
        if (null != attributeFolder) {
            List<TypeGlobalAttribute> globalAttributeList = globalAttributeService.queryByFolderId(id);
            // 属性文件夹下有全局属性则不能删除
            if (CollectionUtils.isEmpty(globalAttributeList)) {
                removeById(id);
            } else {
                throw new BusinessException("You cannot delete an attribute folder with attribute related!", CommonMsgEnum.FAIL.getCode());
            }

        } else {
            throw new ServiceException("Cannot find attribute folder in system!" ,CommonMsgEnum.FAIL.getCode());
        }
    }
}




